# Create your views here.
"""
# 方法一: 基于 APIView 实现视图类
class GoodsListView(APIView):
    def get(self, request, format=None):
        # 获取所有的商品信息， [object1, object2,........]
        goods = Goods.objects.all()
        # 根据指定的 Seriializer 进行序列化对象
        goods_serialzer = GoodsSerializer(goods, many=True)
        # 以 REST 需要的 Response(状态码和数据信息)返回给用户
        return Response(goods_serialzer.data)


# 方法二: 基于GenericAPIView实现视图类
class GoodsListView(generics.ListAPIView):
    # 指定商品的查询集
    queryset = Goods.objects.all()
    # 指定序列化的方式
    serializer_class = GoodsSerializer

    def get(self, request, *args, **kwargs):
        # 不需要自己编写list方法。
        # mixins.ListModelMixin扩展类实现了获取商品详细信息的代码， 因此直接调用即可。
        return self.list(request, *args, **kwargs)
"""
from django.utils.decorators import method_decorator
from django.views.decorators.cache import cache_page
from django.views.decorators.vary import vary_on_cookie
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import mixins, viewsets, filters
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response
from rest_framework.throttling import UserRateThrottle, AnonRateThrottle

from app.goods.filters import GoodsFilter
from app.goods.models import Goods, GoodsCategory, Banner
from app.goods.serializers import GoodsSerializer, CategorySerializer, BannerSerializer


class GoodsPagination(PageNumberPagination):
    '''
    商品列表自定义分页
    '''
    # 默认每页显示的个数
    page_size = 10
    # 可以动态改变每页显示的个数 # http://xxxx/goods/?page=2&page_size=5
    page_size_query_param = 'page_size'
    # 页码参数
    page_query_param = 'page'  # http://xxxx/goods/?page=1
    # 最多能显示多少页
    max_page_size = 100


class GoodsListViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):
    """
    商品列表页
    list: 返回商品列表数据
    retrieve: 返回商品详情数据​
    """

    # # 这里必须要定义一个默认的排序,否则会报错
    # queryset = Goods.objects.all()
    queryset = Goods.objects.all().order_by('id')
    serializer_class = GoodsSerializer

    # 网站限速
    throttle_classes = (UserRateThrottle, AnonRateThrottle)

    # 分页
    pagination_class = GoodsPagination

    # 过滤器：过滤、搜索、排序
    filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
    # 设置filter的类为我们自定义的类
    filter_class = GoodsFilter

    # 搜索,=name表示精确搜索，也可以使用各种正则表达式
    search_fields = ('=name', 'goods_brief')
    # 排序
    ordering_fields = ('sold_num', 'add_time')

    # Cache requested url for each user for 2 hours
    @method_decorator(cache_page(60 * 60 * 2))
    @method_decorator(vary_on_cookie)
    def retrieve(self, request, *args, **kwargs):
        """
        装饰器: 利用 redis 实现缓存
        商品点击数 + 1, 重写retrieve方法， 查看伤情时不仅仅返回商品序列化的信息，还需要修改商品的点击数
        """
        instance = self.get_object()
        # ***************** 增加点击数**************************
        instance.click_num += 1
        instance.save()
        serializer = self.get_serializer(instance)
        return Response(serializer.data)


@method_decorator(cache_page(5), name='dispatch')
class CategoryViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):
    '''
    list:商品分类列表数据, 并利用 redis 实现缓存
    '''
    # queryset = GoodsCategory.objects.all()
    # 希望查询一级分类的信息
    queryset = GoodsCategory.objects.filter(category_type=1)
    serializer_class = CategorySerializer


class BannerViewset(mixins.ListModelMixin, viewsets.GenericViewSet):
    """
    首页轮播图
    """
    queryset = Banner.objects.all().order_by("index")
    serializer_class = BannerSerializer
